{#     Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file #}

{% macro compare_call(op_code, target, left, right, left_choice, right_choice, operand1, operand2) %}
{% if left.getDualType(left_choice) == c_long_desc and right.getDualType(right_choice) == c_digit_desc %}
{% set right = c_long_desc %}
{% endif %}
{% if left.getDualType(left_choice) == c_digit_desc and right.getDualType(right_choice) == c_long_desc %}
{% set left = c_long_desc %}
{% endif %}
COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getDualType(left_choice).getHelperCodeName()}}_{{right.getDualType(right_choice).getHelperCodeName()}}({{left.getDualTypeAccessCode(left_choice, "operand1")}}, {{right.getDualTypeAccessCode(right_choice, "operand2")}})
{% endmacro %}
{{ target.getTypeDecl() }} RICH_COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getHelperCodeName()}}_{{right.getHelperCodeName()}}({{left.getVariableDecl("operand1")}}, {{right.getVariableDecl("operand2")}}) {
    {{ left.getCheckValueCode("operand1") }}
    {{ right.getCheckValueCode("operand2") }}

    bool left_c_usable = {{left.getDualValidityCheckCode("C", "operand1")}};
    bool right_c_usable = {{right.getDualValidityCheckCode("C", "operand2")}};

    if (left_c_usable && right_c_usable) {
{% if left.isSimilarOrSameTypesAsOneOf(n_ilong_desc) or right.isSimilarOrSameTypesAsOneOf(n_ilong_desc) %}
{% if op_code in ("LT", "LE", "EQ") %}
        return {{ compare_call(op_code, target, left, right, "C", "C", "operand1", "operand2") }};
{% else %}
        bool r = {{ compare_call(inverse_compare_op_code, c_bool_desc, left, right, "C", "C", "operand1", "operand2") }};

        // Convert to target type.
        {{ target.getTypeDecl() }} result = {{target.getToValueFromBoolExpression("!r")}};
        {{ target.getTakeReferenceStatement("result", immortal=True) }}
        return result;
{% endif %}
{% else %}
        {{ 0/0 }}
{% endif %}
    } else if (!left_c_usable && !right_c_usable) {
{% if left.isDualType() and right.isDualType() %}
        return RICH_{{ compare_call(op_code, target, left, right, "Python", "Python", "operand1", "operand2") }};
{% elif left.isDualType()  %}
        {{left.getDualTypeEnsurePythonObjectCode("operand1")}}

        return COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getDualType("Python").getHelperCodeName()}}_{{right.getHelperCodeName()}}({{left.getDualTypeAccessCode("Python", "operand1")}}, {{right.getDualTypeAccessCode("C", "operand2")}});
{% elif right.isDualType()  %}
        {{right.getDualTypeEnsurePythonObjectCode("operand1")}}

        return RICH_COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getHelperCodeName()}}_{{right.getDualType("Python").getHelperCodeName()}}({{right.getDualTypeAccessCode("C", "operand1")}}, {{right.getDualTypeAccessCode("Python", "operand2")}});
{% else %}
        {{ 0/0 }}
{% endif %}
    } else {
{% if left.isDualType() and right.isDualType() %}
        bool r;
        if (left_c_usable) {
            r = COMPARE_{{reversed_args_op_code}}_CBOOL_{{right.getDualType("Python").getHelperCodeName()}}_{{left.getDualType("C").getHelperCodeName()}}({{right.getDualTypeAccessCode("Python", "operand2")}}, {{left.getDualTypeAccessCode("C", "operand1")}});
            r = !r;
        } else {
           r = COMPARE_{{op_code}}_CBOOL_{{left.getDualType("Python").getHelperCodeName()}}_{{right.getDualType("C").getHelperCodeName()}}({{left.getDualTypeAccessCode("Python", "operand1")}}, {{left.getDualTypeAccessCode("C", "operand2")}});
        }

        // Convert to target type.
        {{ target.getTypeDecl() }} result = {{target.getToValueFromBoolExpression("r")}};
        {{ target.getTakeReferenceStatement("result", immortal=True) }}
        return result;
{% elif left.isDualType() %}
        return {{ compare_call(op_code, target, left, right, "Python", "C", "operand1", "operand2") }};
{% elif right.isDualType() %}
        return {{ compare_call(reversed_args_op_code, target, right, left, "Python", "C", "operand2", "operand1") }};
{% else %}
        {{ 0/0 }}
{% endif %}
    }

}

{#     Part of "Nuitka", an optimizing Python compiler that is compatible and   #}
{#     integrates with CPython, but also works on its own.                      #}
{#                                                                              #}
{#     Licensed under the Apache License, Version 2.0 (the "License");          #}
{#     you may not use this file except in compliance with the License.         #}
{#     You may obtain a copy of the License at                                  #}
{#                                                                              #}
{#        http://www.apache.org/licenses/LICENSE-2.0                            #}
{#                                                                              #}
{#     Unless required by applicable law or agreed to in writing, software      #}
{#     distributed under the License is distributed on an "AS IS" BASIS,        #}
{#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #}
{#     See the License for the specific language governing permissions and      #}
{#     limitations under the License.                                           #}
